/*!
 * MagicCube Magix Framework v3.0 (Codename: MXFramework)
 *
 * Copyright 2010-2012.
 *
 * Create Date: 2010-11-18 15:50
 */


function $isEmpty(p_value)
{
    return p_value == null || (typeof(p_value) == "string" && p_value.trim() == "");
}

function $notEmpty(p_value)
{
    return !$isEmpty(p_value);
}







// region Boolean
function parseBoolean(p_text)
{
    if (typeof(p_text) == "boolean")
    {
        return p_text;
    }
    t = p_text.toLowerCase();
    return (t == "true") || (t == "t");
};

function $isBoolean(p_value)
{
    return typeof(p_value) == "boolean";
};
// endregion





// region Number
Number.format = function(p_value, p_formatString)
{
    if (p_value == null)
    {
        return "";
    }
    if (typeof(p_formatString) == "undefiend")
    {
        return p_value + "";
    }
    if (typeof(p_formatString) == "number")
    {
        return p_value + "";
    }
    var string = p_value + "";
    if (p_formatString != null && p_formatString != "")
    {
        var stringParts = string.split('.');
        var formatParts = p_formatString.split('.');

        if (stringParts[0].length < formatParts[0].length)
        {
            stringParts[0] =
                formatParts[0].substring(0, formatParts[0].length - stringParts[0].length) +
                stringParts[0];
        }
        if (formatParts.length == 1)
        {
            return stringParts[0];
        }
        else
        {
            if (stringParts.length > 1)
            {
                while (stringParts[1].length < formatParts[1].length)
                {
                    stringParts[1] += "0";
                }
            }
            else
            {
                stringParts[1] = formatParts[1];
            }
            return stringParts[0] + "." + stringParts[1];
        }
    }
    else
    {
        return string;
    }
};

function $isNumber(p_value)
{
    return typeof(p_value) == "number";
};
// endregion








// region String
String.prototype.contains = function(p_subString)
{
    return this.indexOf(p_subString) != -1;
};

String.prototype.startsWith = function(p_string)
{
    return this.substring(0, p_string.length) == p_string;
};

String.prototype.endsWith = function(p_string)
{
    return this.substring(this.length - p_string.length) == p_string;
};

String.prototype.trimLeft = function()
{
    return this.replace(/^\s*/, "");
};

String.prototype.trimRight = function()
{
    return this.replace(/\s*$/, "");
};

String.prototype.trim = function()
{
    return this.trimRight().trimLeft();
};

String.prototype.getByteCount=function()
{
    var text=this.replace(/[^\x00-\xff]/g,"**");
    return text.length;
};

String.prototype.containsAsianCharacters = function()
{
    return (/.*[\u4e00-\u9fa5]+.*$/.test(this));
};

/*
String.prototype.replaceAll = function(p_find, p_replaceWith)
{
    return this.replace(new RegExp(p_find, "gm"), p_replaceWith);
};
*/

function $isString(p_value)
{
    return typeof(p_value) == "string";
};

String.format = function(p_string, p_args)
{
    if (p_string == null)
    {
        return "";
    }
    if (typeof(p_string) != "string")
    {
        p_string = p_string.toString();
    }
    if (p_args == null)
    {
        return p_string;
    }
    
    if (typeof(p_args) == "number")
    {
        var result = new Array(p_args);
        for (var i = 0; i < result.length; i++)
        {
            result[i] = p_string;
        }
        return result.join("");
    }
    
    var result = p_string;
    if (p_string.indexOf("{") != -1 && p_string.indexOf("}") != -1)
    {
        if ($isArray(p_args) || $isPlainObject(p_args))
        {
            for (var i in p_args)
            {
                result = result.replace("{" + i + "}", p_args[i]);
            }
        }
    }
    return result;
};
// endregion








// region Array
Array.prototype.indexOf = function(p_item)
{
    for (var i = 0; i < this.length; i++)
    {
        if (this[i] == p_item)
        {
            return i;
        }
    }
    return -1;
};

Array.prototype.first = function(i)
{
    if (this.length == 0) return null;
    
    if (typeof(i) != "number")
    {
        i = 0;
    }
    if (i >= this.length)
    {
        i = this.length - 1;
    }
    return this[i];
};

Array.prototype.last = function(i)
{
    if (this.length == 0) return null;
    
    if (typeof(i) != "number")
    {
        i = 0;
    }
    if (this.length - i - 1 >= 0)
    {
        return this[this.length - i - 1];
    }
    else
    {
        return this[0];
    }
};

Array.prototype.contains = function(p_item)
{
    return this.indexOf(p_item) != -1;
};

Array.prototype.add = function(p_item)
{
    return this[this.length] = p_item;
};

Array.prototype.insert = function(p_startIndex, p_item)
{
    return this.splice(p_startIndex, 0, p_item);
};

Array.prototype.insertBefore = function(p_item, p_beforeItem)
{
    var index = this.indexOf(p_beforeItem);
    if (index == -1)
    {
        return false;
    }
    
    this.insert(index, p_item);
    return true;
};

Array.prototype.insertAfter = function(p_item, p_afterItem)
{
    var index = this.indexOf(p_beforeItem);
    if (index == -1)
    {
        return false;
    }
    else if (index == this.length)
    {
        this.add(p_item);
        return true;
    }
    else
    {
        this.insert(index + 1, p_item);
        return true;
    }
};

Array.prototype.remove = function(p_item)
{
    return this.removeAt(this.indexOf(p_item));
};

Array.prototype.removeAt = function(p_index)
{
    if (p_index >= 0 && p_index < this.length)
    {
        this.splice(p_index, 1);
        return true;
    }
    else
    {
        return false;
    }
};

Array.prototype.removeLast = function(p_index)
{
    if (this.length == 0) return;
    
    if (typeof(p_index) != "number")
    {
        p_index = 0;
    }
    
    var i = this.length - p_index - 1;
    this.removeAt(i);
}

Array.prototype.clear = function()
{
    if (this.length > 0)
    {
        this.splice(0, this.length);
    }
};

Array.prototype.clone = function()
{
    return this.slice(0, this.length);
};

Array.prototype.swap = function(p_item1, p_item2)
{
    var index1 = this.indexOf(p_item1);
    var index2 = this.indexOf(p_item2);   
    
    this[index1] = p_item2;
    this[index2] = p_item1;
};

function $isArray(p_value)
{
    return p_value != null && (typeof(p_value) == "object" && typeof(p_value.length) == "number")
};
// endregion




function $isPlainObject(p_value)
{
    return $.isPlainObject(p_value);
}











var __regex_yyyyM = /^(\S*)-(\S*)$/;
var __regex_yyyyMD = /^(\S*)-(\S*)-(\S*)$/;
var __regex_Hms = /^(\S*):(\S*):(\S*)$/;
var __regex_Hm = /^(\S*):(\S*)$/;
// region Date
function parseDate(p_text)
{
    if (p_text == null || (typeof(p_text) == "string" && p_text.trim() == ""))
    {
        return null;
    }
    if ($isDate(p_text))
    {
       return p_text;
    }
    
    var y = 1900;
    var M = 1;
    var d = 1;
    var H = 0;
    var m = 0;
    var s = 0;
    
    var parts = null;
    var datePart = null;
    var timePart = null;
    p_text = p_text.trim();
    if (p_text.indexOf(" ") != -1)
    {
        parts = p_text.split(" ");
    }
    else if (p_text.indexOf("T") != -1)
    {
        parts = p_text.split("T");
    }
    
    if (parts == null)
    {
        parts = [p_text];
    }
    
    if (parts.length == 1)
    {
        if (parts[0].indexOf(":") != -1)
        {
            timePart = parts[0];
        }
        else
        {
            datePart = parts[0];
        }
    }
    else if (parts.length == 2)
    {
        datePart = parts[0];
        timePart = parts[1];
    }
    
    if (datePart != null)
    {
        var matches = datePart.match(__regex_yyyyMD);
        if (matches == null)
        {
            matches = datePart.match(__regex_yyyyM);
            if (matches != null)
            {
               timePart = null;
            }
            else
            {
                matches = [datePart, datePart];
            }
        }
        if (matches != null)
        {
            if (matches.length >= 2)
            {
                y = parseInt(matches[1], 10);
                if (isNaN(y))
                {
                    y = 1900;
                }
            }
            
            if (matches.length >= 3)
            {
                M = parseInt(matches[2], 10);
                if (isNaN(M) || M > 12 || M <= 0)
                {
                    M = 1;
                }
            }
            
            if (matches.length >= 4)
            {
                var d_max = Date.getDaysInMonth(y, M - 1);
                d = parseInt(matches[3], 10);
                if (isNaN(d) || d <= 0)
                {
                    d = 1;
                }
                else if (d > d_max)
                {
                    d = d_max;
                }
            }
        }
    }
    
    if (timePart != null)
    {
        var matches = timePart.match(__regex_Hms);
        if (matches == null)
        {
            matches = timePart.match(__regex_Hm);
            if (matches == null)
            {
                matches = [timePart, timePart];
            }
        }
        
        if (matches.length >= 2)
        {
            H = parseInt(matches[1], 10);
            if (isNaN(H) || H > 23 || H < 0)
            {
                H = 0;
            }
        }
        
        if (matches.length >= 3)
        {
            m = parseInt(matches[2], 10);
            if (isNaN(m) || m > 60 || m < 0)
            {
                m = 0;
            }
        }
        
        if (matches.length >= 4)
        {
            s = parseInt(matches[3], 10);
            if (isNaN(s) || s > 60 || s < 0)
            {
                s = 0;
            }
        }
    }
    
    return new Date(y, M - 1, d, H, m, s);
};

function $isDate(p_value)
{
    return p_value != null && p_value.constructor == Date;
};


Date.today = new Date();
Date.today = new Date(Date.today.getFullYear(), Date.today.getMonth(), Date.today.getDate());

Date.format = function(p_value, p_formatString)
{
    if (p_value != null)
    {
        var text;
        if (!p_formatString)
        {
            text = "yyyy-MM-dd HH:mm:ss";
        }
        else
        {
            text = p_formatString;
        }
        var yy = p_value.getYear();
        var M = p_value.getMonth() + 1;
        var d = p_value.getDate();
        var h = p_value.getHours() % 12;
        var H = p_value.getHours();
        var m = p_value.getMinutes();
        var s = p_value.getSeconds();
    
        var yyyy = p_value.getFullYear();
        var MM = Number.format(M, "00");
        var dd = Number.format(d, "00");
        var hh = Number.format(h, "00");
        var HH = Number.format(H, "00");
        var mm = Number.format(m, "00");
        var ss = Number.format(s, "00");
        text = text.replace("yyyy", yyyy).replace("MM", MM).replace("dd", dd);
        text = text.replace("HH", HH).replace("hh", hh).replace("mm", mm).replace("ss", ss);
        text = text.replace("yy", yy).replace("M", M).replace("d", d);
        text = text.replace("H", H).replace("h", h).replace("m", m).replace("s", s);
        return text;
    }
    else
    {
        return "";
    }
};

Date.getDaysInMonth = function(p_year, p_month)
{
    switch (p_month + 1)
    {
        case 2:
            if ( (p_year % 400 == 0) || (p_year % 4 == 0) && (p_year % 100 != 0))
            {
                return 29;
            }
            else
            {
                return 28;
            }
        case 1: case 3: case 5:
        case 7: case 8: case 10: case 12:
            return 31;
        default:
            return 30;
    }
};

Date.prototype.addSeconds = function(p_seconds)
{
    return new Date(this * 1 + p_seconds * 1000);
};

Date.prototype.addMinutes = function(p_minutes)
{
    return this.addSeconds(p_minutes * 60);
};

Date.prototype.addHours = function(p_hours)
{
    return this.addMinutes(p_hours * 60);
};

Date.prototype.addDays = function(p_days)
{
    return this.addHours(p_days * 24);
};

Date.prototype.addWeeks = function(p_weeks)
{
    return this.addDays(p_weeks * 7);
};

Date.prototype.addMonths = function(p_months)
{
    var copy = new Date(this * 1);
    var months = copy.getMonth() + 1 + p_months;
    
    var years = Math.floor(months / 12);
    
    var year = copy.getFullYear() + years;
    var month = Math.abs(years * 12 - months) % 12;
    var date = copy.getDate();
    var daysInMonth = Date.getDaysInMonth(year, month - 1);
    
    if (date > daysInMonth)
    {
        date = daysInMonth;
    }
    
    copy.setDate(1);
    copy.setFullYear(year);
    copy.setMonth(month - 1);
    copy.setDate(date);
    
    return copy;
};

Date.prototype.addYears = function(p_years)
{
    var copy = this.addMonths(p_years * 12);
    return copy;
};

Date.prototype.clone = function()
{
    return new Date(this * 1);
};
// endregion







// region Function
function $isFunction(p_value)
{
    return typeof(p_value) == "function";
}
// endregion








// region Misc ($format, $compare, $isIE, XmlDocument, XmlHttpRequest)
function $format(p_value, p_format)
{
    if ($isString(p_value) && ($isArray(p_format) || $isNumber(p_format)))
    {
        return String.format(p_value, p_format);
    }
    if ($isNumber(p_value))
    {
        return Number.format(p_value, p_format);
    }
    else if ($isDate(p_value))
    {
        return Date.format(p_value, p_format);
    }
    else
    {
        return p_value != null ? p_value.toString() : "";
    }
}



function $isEqual(p_value1, p_value2, p_ignoreCase)
{
    if (p_ignoreCase == null)
    {
        p_ignoreCase = false;
    }
    if (p_ignoreCase)
    {
        if (typeof(p_value1) == "string")
        {
            p_value1 = p_value1.toLowerCase();
        }
        if (typeof(p_value2) == "string")
        {
            p_value2 = p_value2.toLowerCase();
        }
    }
    
    if ($isArray(p_value1) && $isArray(p_value2))
    {
        if (p_value1.length != p_value2.length) return false;
        for (var i = 0; i < p_value1.length; i++)
        {
            if (!$isEqual(p_value1[i], p_value2[i], p_ignoreCase))
            {
                return false;
            }                     
        }
        return true;
    }
    
    if (p_value1 == p_value2)
    {
        return true;
    }
    if (p_value1 == null && p_value2 != null)
    {
        return false;
    }
    else if (p_value1 != null && p_value2 == null)
    {
        return false;
    }
    else
    {
        return p_value1.valueOf() == p_value2.valueOf();
    }
}

function $notEqual(p_value1, p_value2, p_ignoreCase)
{
    return !$isEqual(p_value1, p_value2, p_ignoreCase);
}


function $compare(p_value1, p_value2, p_ignoreCase)
{
    if (p_ignoreCase == null)
    {
        p_ignoreCase = false;
    }
    if (p_ignoreCase)
    {
        if (typeof(p_value1) == "string")
        {
            p_value1 = p_value1.toLowerCase();
        }
        if (typeof(p_value2) == "string")
        {
            p_value2 = p_value2.toLowerCase();
        }
    }
    
    if ($isEqual(p_value1 == p_value2))
    {
        return 0;
    }
    else
    {
        if (typeof(p_value1) == "string")
        {
            return p_value1.localeCompare(p_value2);
        }
        else if ($isNumber(p_value1) || $isDate(p_value1))
        {
            return p_value2.valueOf() - p_value1.valueOf();
        }
        else
        {
            return 1;
        }
    }
}







function $isIE()
{
    return (window.navigator.userAgent.toLowerCase().indexOf("msie") != -1)
} 

if ($isIE())
{
    if (typeof(XMLHttpRequest) == "undefined")
    {
        var XMLHttpRequest = function()
        {
            try
            {
                return new ActiveXObject("MSXML2.XMLHTTP");
            }
            catch (e)
            {
            }
            return null;
        }
        
        XmlDocument = function()
        {
            var me = new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
            me.async = false;
            return me;
        }
    }
}
else
{
    HTMLElement.prototype.__defineSetter__("innerText",function(sText)
    {
        return this.textContent = sText;
    });
    HTMLElement.prototype.__defineGetter__("innerText",function()
    {
        return this.textContent;
    });
    HTMLElement.prototype.contains = function(node)
    {
        do if(node == this)return true;
        while(node = node.parentNode);
        return false;
    };
    
    
    XmlDocument = function()
    {
        var result = document.implementation.createDocument("", "", null);
        result.async = false;
        return result;
    };
    
    XMLDocument.prototype.loadXML = function(xmlString)
    {
        var childNodes = this.childNodes;
        for (var i = childNodes.length - 1; i >= 0; i--)
            this.removeChild(childNodes[i]);

        var dp = new DOMParser();
        var newDOM = dp.parseFromString(xmlString, "text/xml");
        var newElt = this.importNode(newDOM.documentElement, true);
        this.appendChild(newElt);
    };

    XMLDocument.prototype.__defineGetter__("xml", function ()
    { 
        try
        { 
            return new XMLSerializer().serializeToString(this); 
        }
        catch(ex)
        { 
            var d = document.createElement("div"); 
            d.appendChild(this.cloneNode(true)); 
            return d.innerHTML; 
        } 
    });
    
    Element.prototype.__defineGetter__("xml", function ()
    { 
        try
        { 
            return new XMLSerializer().serializeToString(this); 
        }
        catch(ex)
        { 
            var d = document.createElement("div"); 
            d.appendChild(this.cloneNode(true)); 
            return d.innerHTML; 
        }
    }); 
    
    XMLDocument.prototype.__defineGetter__("text", function ()
    { 
        return this.firstChild.textContent; 
    }); 
    
    Element.prototype.__defineGetter__("text", function ()
    { 
        return this.textContent; 
    }); 
    
    Element.prototype.__defineSetter__("text", function (value)
    { 
        this.textContent = value;
    }); 
    
    CDATASection.prototype.__defineGetter__("text", function ()
    { 
        return this.textContent; 
    }); 
    
    CDATASection.prototype.__defineSetter__("text", function (value)
    { 
        this.textContent = value;
    }); 

    XMLDocument.prototype.selectSingleNode = Element.prototype.selectSingleNode = function (xpath)
    { 
        var x = this.selectNodes(xpath); 
        if (!x || x.length < 1) return null; 
        return x[0]; 
    } 
    
    XMLDocument.prototype.selectNodes = Element.prototype.selectNodes = function (xpath)
    { 
        var xpe = new  XPathEvaluator(); 
        var nsResolver = xpe.createNSResolver(this.ownerDocument == null ? this.documentElement: this .ownerDocument.documentElement); 
        var result = xpe.evaluate(xpath, this, nsResolver, 0, null); 
        var found = []; 
        var res; 
        while (res = result.iterateNext()) found.push(res); 
        return  found; 
    }
}
XmlHttpRequest = XMLHttpRequest;



Guid = {newGuid : function(p_toLowerCase, p_length)
{
    var toLowerCase = false;
    if (p_toLowerCase != null)
    {
        toLowerCase = p_toLowerCase;
    }
    var length = 32;
    if (p_length != null)
    {
        length = p_length;
    }
    var result = "";
    for (var i = 1; i <= length; i++)
    {
        var n = Math.floor(Math.random() * 16.0);
        if (n < 10)
        {
            result += n;            
        }
        else if (n == 10)
        {
            result += "a";
        }
        else if (n == 11)
        {
            result += "b";
        }
        else if (n == 12)
        {
            result += "c";
        }
        else if (n == 13)
        {
            result += "d";
        }
        else if (n == 14)
        {
            result += "e";
        }
        else if (n == 15)
        {
            result += "f";
        }
        if ((i == 8) || (i == 12) || (i == 16) || (i == 20))
        {
            result += "-";
        }
    }
    
    if (toLowerCase)
    {
        result = result.toLowerCase();
    }
    else
    {
        result = result.toUpperCase();
    }
    return result;
}};
// endregion







// region Event
Event = function()
{
    var me = this;
    
    me.listeners = [];
    
    me.addEventListener = function(p_listener)
    {
        if (!me.listeners.contains(p_listener))
        {
            me.listeners.add(p_listener);
        }
    };
    
    me.insertEventListener = function(p_index, p_listener)
    {
        if (typeof(p_listener) == "function")
        {
            if (!me.listeners.contains(p_listener))
            {
                me.listeners.insert(p_index, p_listener);
            }
        }
        else
        {
            throw new Error($err("NON_NULLABLE", ["p_listener"]));
        }
    };
    
    me.removeEventListener = function(p_listener)
    {
        return me.listeners.remove(p_listener);
    };
    
    me.clear = function()
    {
        me.listeners.clear();
    };
    
    me.fire = function(e)
    {
        if (me.listeners.length == 0) return;
        
        for (var i = 0; i < me.listeners.length; i++)
        {
            var h = me.listeners[i];
            if (typeof(h) == "function")
            {
                me.listeners[i](e);
            }
        }
    };
    
    return me;
}


EventDispatcher = function()
{
    var me = this;
    
    me.addEventListener = function(p_eventType, p_function)
    {
        if (!p_eventType.startsWith("on"))
        {
            p_eventType = "on" + p_eventType;
        }
        if (typeof(me[p_eventType]) == "undefined")
        {
            throw new Error($err("UNDEFINED_EVENT", [p_eventType]));
        }
        if (me[p_eventType] == null)
        {
            me[p_eventType] = new Event();
        }
        me[p_eventType].addEventListener(p_function);
    };
    me.bind = me.addEventListener;
    
    me.removeEventListener = function(p_eventType, p_function)
    {
        if (p_eventType == null && p_function == null)
        {
            for (var name in this)
            {
                if (this[name] != null && this[name].constructor == Event)
                {
                    this[name].clear();
                    this[name] = null;
                }
            }
        }
        else
        {
            if (!p_eventType.startsWith("on"))
            {
                p_eventType = "on" + p_eventType;
            }
            if (typeof(me[p_eventType]) == "undefined")
            {
                throw new Error($err("UNDEFINED_EVENT", [p_eventType]));
            }
            
            if (me[p_eventType] != null)
            {
                if (p_function != null)
                {
                    me[p_eventType].removeEventListener(p_function);
                }
                else
                {
                    me[p_eventType].clear();
                }
            }
        }
    };
    me.unbind = me.removeEventListener;
    
    me.hasEventListener = function(p_eventType)
    {
        if (!p_eventType.startsWith("on"))
        {
            p_eventType = "on" + p_eventType;
        }
        if (typeof(me[p_eventType]) == "undefined")
        {
            return false;
        }
        if (me[p_eventType] != null)
        {
            return me[p_eventType].listeners.length > 0;
        }
        else
        {
            return false;
        }
    };
    me.hasBound = me.hasEventListener;
    
    me.dispatchEvent = function(p_eventType, p_args)
    {
        if (!p_eventType.startsWith("on"))
        {
            p_eventType = "on" + p_eventType;
        }
        if (typeof(me[p_eventType]) == "undefined")
        {
            throw new Error($err("UNDEFINED_EVENT", [p_eventType]));
        }
        if (me[p_eventType] != null)
        {
            var e = null;
            if (p_args != null)
            {
                e = p_args;
            }
            else
            {
                e = {};
            }
            e.target = me;
            
            var eventType = p_eventType;
            if (eventType.startsWith("on"))
            {
                eventType = eventType.substr(2);
            }
            e.type = eventType;
            
            me[p_eventType].fire(e);
        }
    };
    me.trigger = me.dispatchEvent;
    
    me.dispose = function()
    {
        me.unbind();
        me.disposed = true;
    };
    
    return me;
};
// endregion




















// region MapPath, $include, $import, $namespace
function $mappath(p_url)
{
    if (typeof (p_url) != "string") return null;
    if (p_url.startsWith("~/"))
    {
        p_url = $mx.rootPath + p_url.substr(1);
    }
    
    if (p_url.indexOf("$locale") != -1)
    {
        p_url = p_url.replace("$locale", $mx.locale);
    }
    else if (p_url.startsWith("$lib"))
    {
        p_url = p_url.replace("$lib", $mx.libPath);
    }
    else if (p_url.startsWith("$themes"))
    {
        p_url = p_url.replace("$themes", $mx.themesPath);
    }
    else if (p_url.startsWith("$theme"))
    {
        p_url = p_url.replace("$theme", $mx.themePath);
    }
    else if (p_url.startsWith("$google") && typeof(g) != "undefined")
    {
        p_url = p_url.replace("$google", g.baseUrl);
    }
    return p_url;
}



var $mx_load = {};
$(function() { $mx.pageLoaded = true; });
function $include(p_url, p_ajaxLoad)
{
    if (!$mx.debugMode)
    {
        if (p_url.startsWith("$theme/") && p_url.endsWith(".css"))
        {
            if ($mx.gzip)
            {
                p_url = $mappath("$theme/gzip.css");
            }
            else
            {
                p_url = $mappath("$theme/min.css");
            }
        }
    }
    
    
    var url = $mappath(p_url);
    
    if ($mx_load[p_url] != null)
    {
        return;
    }
    $mx_load[url] = $mx.pageLoaded;
    
    if ($mx.pageLoaded == true || p_ajaxLoad)
    {
        if (url.endsWith(".js"))
        {
            if ($mx.debugMode)
            {
                url += "?rnd=" + Math.random();
            }
            $.ajax({url: url, async: false});
        }
        else
        {
            if ($mx.debugMode)
            {
                url += "?rnd=" + Math.random();
            }
            var link = document.createElement("link");
            link.rel = "stylesheet";
            link.type = "text/css";
            link.href = url;
            var head = document.getElementsByTagName("head");
            if (head.length > 0)
            {
                head[0].appendChild(link);
            }
        }
    }
    else
    {        
        if (url.endsWith(".js"))
        {
            document.write("<script type='text/javascript' src='" + url + "'></script>");
        }
        else if (url.endsWith(".css"))
        {
            document.write("<link type='text/css' rel='stylesheet' href='" + url + "'></link>");
        }
    }
}

function $import(p_classFullName, p_ajaxLoad)
{
    if ($mx.debugMode)
    {
        if (p_classFullName.startsWith("lib."))
        {
            var url = $mx.scriptPath + "/" + p_classFullName.replace(/\./g, "/") + ".js";
            $include(url, p_ajaxLoad);
        }
        else
        {
            var url = $mx.scriptPath + "/" + p_classFullName.replace(/\./g, "/") + ".js";
            $include(url, p_ajaxLoad);
        }
    }
    else
    {
        
        for (var i = 0; i < $mx_assemblies.length; i++)
        {
            var assembly = $mx_assemblies[i];
            if (assembly.name == "mx") continue;
            var fn = assembly.name + ".";
            if (p_classFullName.startsWith(fn))
            {
                var url = $mx.scriptPath + "/" + assembly.path;
                $include(url, p_ajaxLoad);
            }
        }
    }
}

function $namespace(p_namespace)
{
    var parts = p_namespace.split(".");
    if (parts.length == 0)
    {
        return null;
    }
    try
    {
        eval(parts[0]);
    }
    catch (e)
    {
        eval(parts[0] + " = {};");
    }
    var root = eval(parts[0]);
    var space = parts[0];
    for (var i = 1; i < parts.length; i++)
    {
        space += "." + parts[i];
        if (!eval(space))
        {
            eval(space + " = {};");
        }
    }
    return eval(p_namespace);
}
$ns = $namespace;
// endregion






var $mx_dicts = {};
function $importdict(p_dict)
{
    if (typeof($mx_dicts[p_dict]) == "undefined")
    {
        var url = $mappath("~/scripts/src/" + p_dict.replace(/\./g, "/") + "/_locales/$locale/messages.js" + ($mx.debugMode ? "?rnd=" + Math.random() : ""));
        var json = $.getSync(url, null, "text");
        $mx_dicts[p_dict] = eval("(" + json + ")");
    }
    var dict = $mx_dicts[p_dict];
    if (dict == null)
    {
        throw new Error("Dictionary '" + p_dict + "' not found in the current locale.");
    }
    return dict;
}

function $msg(p_dict, p_key, p_args)
{   
    if (p_dict == null && p_key == null && p_args == null)
    {
        return "";
    }
    
    if (p_dict != null && p_key != null && p_args == null)
    {
        if (typeof(p_key) == "object")
        {
            p_args = p_key;
            p_key = p_dict;
            p_dict = null;
        }
    }
    else if (p_dict != null && p_key == null && p_args == null)
    {
        p_key = p_dict;
        p_dict = null;
    }
    
    if (p_dict != null && p_dict.indexOf(",") != -1)
    {
        var parts = p_dict.split(",");
        for (var i = 0; i < parts.length; i++)
        {
            var result = $msg(parts[i].trim(), p_key, p_args);
            if (result != null && result != "")
            {
                return result;
            }
        }
        return "";
    }
    else
    {
        if (p_key != null)
        {
            if (p_dict == null)
            {
                p_dict = "mx";
            }
            var dict = $importdict(p_dict);
            var result = dict[p_key.toUpperCase()];
            if (result == null)
            {
                result = $mx_dicts["mx"][p_key.toUpperCase()];
            }
            return String.format(result, p_args);
        }
        else
        {
            return "";
        }
    }
}

function $err(p_dict, p_key, p_args)
{
    if (p_dict == null && p_key == null && p_args == null)
    {
        return "";
    }
    
    if (p_dict != null && p_key != null && p_args == null)
    {
        if (typeof(p_key) == "object")
        {
            p_args = p_key;
            p_key = p_dict;
            p_dict = null;
        }
    }
    else if (p_dict != null && p_key == null && p_args == null)
    {
        p_key = p_dict;
        p_dict = null;
    }
    
    return $msg(p_dict, "ERR_" + p_key, p_args);
}

function $translate(p_container)
{
    var html = null;
    if (typeof(p_container) == "string")
    {
        html = p_container;
    }
    else
    {
        html = p_container.innerHTML;
    }
    var placeHolders = html.match(/\$\{([A-Z_0-9]*)\}/g);
    if (placeHolders != null)
    {
        for (var i = 0; i < placeHolders.length; i++)
        {
            var name = placeHolders[i].substr(2, placeHolders[i].length - 3);
            html = html.replace(placeHolders[i], $msg("fp,mx", name));
        }
        if (typeof(p_container) == "string")
        {
            return html;
        }
        else
        {
            p_container.innerHTML = html;
        }
    }
}



UserError = function(p_message)
{
    var me = new Error(p_message);
    
    me.type = "UserError";
    
    return me;
};

function isUserError(p_err)
{
    return (p_err != null && p_err.type == "UserError");
}








// region Init
var $mx = null;
function $mx_init()
{
    $mx = {};
        
    var scripts = document.getElementsByTagName("script");
    var src = scripts[scripts.length - 1].src;
    if (src.endsWith("/scripts/src/mx/framework.js"))
    {
        var rootPath = src.substr(0, src.length - "/scripts/src/mx/framework.js".length);
        rootPath = rootPath.replace(location.protocol + "//" + location.host, "");
        
        $mx.debugMode = true;
        $mx.rootPath = rootPath;
        $mx.scriptPath = rootPath + "/scripts/src";
    }
    else if (src.endsWith("/scripts/min/mx.js"))
    {
        var rootPath = src.substr(0, src.length - "/scripts/min/mx.js".length);
        rootPath = rootPath.replace(location.protocol + "//" + location.host, "");
        
        $mx.debugMode = false;
        $mx.rootPath = rootPath;
        $mx.scriptPath = rootPath + "/scripts/min";
    }
    else if (src.endsWith("/scripts/gzip/mx.js"))
    {
        var rootPath = src.substr(0, src.length - "/scripts/gzip/mx.js".length);
        rootPath = rootPath.replace(location.protocol + "//" + location.host, "");
        
        $mx.debugMode = false;
        $mx.rootPath = rootPath;
        $mx.scriptPath = rootPath + "/scripts/gzip";
        $mx.gzip = true;
    }
    else
    {
        throw new Error($msg("MX_NOT_UNINITIALIZED"));
    }
    
    $mx.locale = (typeof($mx_locale) != "undefined" ? $mx_locale : "en");
    $mx.pageLoaded = false;
    $mx.theme = (typeof($mx_theme) != "undefined" ? $mx_theme : "leopard");
    $mx.themesPath = $mx.rootPath + "/themes";
    $mx.themePath = $mx.themesPath + "/" + $mx.theme;
}
$mx_init();
// endregion



$include("$theme/framework.css");
$include("~/themes/fonts/pictos.css");

$ns("mx");
$importdict("mx");
$import("mx.utils.SymbolUtil");
$import("mx.indication");
$import("mx.controls.JQControl");